home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
TUTORC.ZIP
/
TUT9.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-30
|
15KB
|
447 lines
/*
tut9.c
10/30/94
from tutprog9.pas
Adapted from Denthor's tutprog9.pas
Translated into C, from Denthor's VGA Trainer, by
Steve Pinault, scp@ohm.att.com
Compiled with Microsoft Visual C++ 1.5 (Microsoft C 8.0)
To compile:
First compile the subroutines in tutsubs.c with the batch file
cltutsub.bat
Then compile any of the tutor programs with the batch file
cltut.bat
Example: C:>cltutsub
C:>cltut tut9.c
to compile this program.
*/
#include "tutheadr.h"
#define maxpolys 5
int A[maxpolys][4][3] =
{
{{-10,10,0},{-2,-10,0},{0,-10,0},{-5,10,0}},
{{10,10,0},{2,-10,0},{0,-10,0},{5,10,0}},
{{-2,-10,0},{2,-10,0},{2,-5,0},{-2,-5,0}},
{{-6,0,0},{6,0,0},{7,5,0},{-7,5,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
}; // { The 3-D coordinates of our object ... stored as (X1,Y1,Z1}, }
// { (X2,Y2,Z2} ... for the 4 points of a poly }
int S[maxpolys][4][3] =
{
{{-10,-10,0},{10,-10,0},{10,-7,0},{-10,-7,0}},
{{-10,10,0},{10,10,0},{10,7,0},{-10,7,0}},
{{-10,1,0},{10,1,0},{10,-2,0},{-10,-2,0}},
{{-10,-8,0},{-7,-8,0},{-7,0,0},{-10,0,0}},
{{10,8,0},{7,8,0},{7,0,0},{10,0,0}}
}; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
//{ {X2,Y2,Z2} ... for the 4 points of a poly }
int P[maxpolys][4][3] =
{
{{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}},
{{10,-10,0},{7,-10,0},{7,0,0},{10,0,0}},
{{-9,-10,0},{9,-10,0},{9,-7,0},{-9,-7,0}},
{{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
}; // { The 3-D coordinates of our object ... stored as (X1,Y1,Z1}, }
// { (X2,Y2,Z2} ... for the 4 points of a poly }
int H[maxpolys][4][3] =
{
{{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}},
{{10,-10,0},{7,-10,0},{7,10,0},{10,10,0}},
{{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
}; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
// { (X2,Y2,Z2} ... for the 4 points of a poly }
int Y[maxpolys][4][3] =
{
{{-7,-10,0},{0,-3,0},{0,0,0},{-10,-7,0}},
{{7,-10,0},{0,-3,0},{0,0,0},{10,-7,0}},
{{-2,-3,0},{2,-3,0},{2,10,0},{-2,10,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
}; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
// { {X2,Y2,Z2} ... for the 4 points of a poly }
int X[maxpolys][4][3] =
{
{{-7,-10,0},{10,7,0},{7,10,0},{-10,-7,0}},
{{7,-10,0},{-10,7,0},{-7,10,0},{10,-7,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
}; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
// { {X2,Y2,Z2} ... for the 4 points of a poly }
int I[maxpolys][4][3] =
{
{{-10,-10,0},{10,-10,0},{10,-7,0},{-10,-7,0}},
{{-10,10,0},{10,10,0},{10,7,0},{-10,7,0}},
{{-2,-9,0},{2,-9,0},{2,9,0},{-2,9,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
}; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
// { {X2,Y2,Z2) ... for the 4 points of a poly }
struct Point Lines[maxpolys][4];
struct Point translated[maxpolys][4];
int xoff,yoff,zoff;
float lookup[360][2];
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure DrawPoly(x1,y1,x2,y2,x3,y3,x4,y4:integer;color:byte;where:word);
// { This draw a polygon with 4 points at x1,y1 , x2,y2 , x3,y3 , x4,y4
// in color col }
void DrawPoly(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, char color, int where)
{
int x;
int mny,mxy;
int mnx,mxx,yc;
int mul1,div1,mul2,div2,mul3,div3,mul4,div4;
mny=y1; mxy=y1;
if (y2<mny) mny=y2;
if (y2>mxy) mxy=y2;
if (y3<mny) mny=y3;
if (y3>mxy) mxy=y3; // { Choose the min y mny and max y mxy }
if (y4<mny) mny=y4;
if (y4>mxy) mxy=y4;
if (mny<0) mny=0;
if (mxy>199) mxy=199;
if (mny>199) return;
if (mxy<0) return; // { Verticle range checking }
mul1=x1-x4; div1=y1-y4;
mul2=x2-x1; div2=y2-y1;
mul3=x3-x2; div3=y3-y2;
mul4=x4-x3; div4=y4-y3; // { Constants needed for intersection calc }
for (yc=mny;yc<=mxy;yc++)
{
mnx=320;
mxx=-1;
if ((y4>=yc) || (y1>=yc))
if ((y4<=yc)|| (y1<=yc)) // { Check that yc is between y1 and y4 }
if (!(y4==y1))
{
x=(yc-y4)*mul1/div1+x4; // { Point of intersection on x axis }
if (x<mnx)
mnx=x;
if (x>mxx)
mxx=x; // { Set point as start or end of horiz line }
}
if ((y1>=yc) || (y2>=yc))
if ((y1<=yc) || (y2<=yc))// { Check that yc is between y1 and y2 }
if (!(y1==y2))
{
x=(yc-y1)*mul2 / div2+x1; // { Point of intersection on x axis }
if (x<mnx)
mnx=x;
if (x>mxx)
mxx=x; // { Set point as start or end of horiz line }
}
if ((y2>=yc) || (y3>=yc))
if ((y2<=yc) || (y3<=yc)) // { Check that yc is between y2 and y3 }
if (!(y2==y3))
{
x=(yc-y2)*mul3 / div3+x2; //{ Point of intersection on x axis }
if (x<mnx)
mnx=x;
if (x>mxx)
mxx=x; // { Set point as start or end of horiz line }
}
if ((y3>=yc) || (y4>=yc))
if ((y3<=yc) || (y4<=yc)) // { Check that yc is between y3 and y4 }
if (!(y3==y4))
{
x=(yc-y3)*mul4 / div4+x3; // { Point of intersection on x axis }
if (x<mnx)
mnx=x;
if (x>mxx)
mxx=x; // { Set point as start or end of horiz line }
}
if (mnx<0)
mnx=0;
if (mxx>319)
mxx=319; // { Range checking on horizontal line }
if (mnx<=mxx)
Hline (mnx,mxx,yc,color,where);
// { Draw the horizontal line }
}
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure SetUpPoints;
// { This creates the lookup table }
void SetUpPoints()
{
int loop1;
for(loop1=0;loop1<360;loop1++)
{
lookup [loop1][0]=(float)sin((double)rad((float)loop1));
lookup [loop1][1]=(float)cos((double)rad((float)loop1));
}
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure RotatePoints (X,Y,Z:Integer);
// { This rotates object lines by X,Y and Z; then places the result in
// TRANSLATED }
// rotate about x: newy = cos*y-sin*z (cos*cos-sin*sin)
// newz = sin*y+cos*z (sin*cos+cos*sin)
// i.e: newy+i*newz=e^(i*theta)*(y+i*z) (theta=int x)
// =(cos+i*sin)*(y+i*z)
// translated[loop1][0] and translated[loop1][1] are the two endpoints
// of line segment loop1.
//
void RotatePoints(int x, int y, int z)
{
int loop1,loop2;
struct Point temp;
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
temp.x=Lines[loop1][loop2].x;
temp.y=lookup[x][1]*Lines[loop1][loop2].y - lookup[x][0]*Lines[loop1][loop2].z;
temp.z=lookup[x][0]*Lines[loop1][loop2].y + lookup[x][1]*Lines[loop1][loop2].z;
translated[loop1][loop2]=temp;
temp.x=lookup[y][1]*translated[loop1][loop2].x-lookup[y][0]*translated[loop1][loop2].y;
temp.y=lookup[y][0]*translated[loop1][loop2].x+lookup[y][1]*translated[loop1][loop2].y;
temp.z=translated[loop1][loop2].z;
translated[loop1][loop2]=temp;
temp.z=lookup[z][1]*translated[loop1][loop2].z-lookup[z][0]*translated[loop1][loop2].x;
temp.x=lookup[z][0]*translated[loop1][loop2].z+lookup[z][1]*translated[loop1][loop2].x;
temp.y=translated[loop1][loop2].y;
translated[loop1][loop2]=temp;
}
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure DrawPoints;
// { This draws the translated object to the virtual screen }
void DrawPoints()
{
int loop1;
int nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3;
int temp0,temp1,temp2,temp3;
for(loop1=0;loop1<maxpolys;loop1++)
{
temp0=round (translated[loop1][0].z+zoff);
temp1=round (translated[loop1][1].z+zoff);
temp2=round (translated[loop1][2].z+zoff);
temp3=round (translated[loop1][3].z+zoff);
if((temp0<0)&&(temp1<0)&&(temp2<0)&&(temp3<0))
{
nx0 =round (256*translated[loop1][0].x) / temp0 + xoff;
ny0 =round (256*translated[loop1][0].y) / temp0 + yoff;
nx1 =round (256*translated[loop1][1].x) / temp1 + xoff;
ny1 =round (256*translated[loop1][1].y) / temp1 + yoff;
nx2 =round (256*translated[loop1][2].x) / temp2 + xoff;
ny2 =round (256*translated[loop1][2].y) / temp2 + yoff;
nx3 =round (256*translated[loop1][3].x) / temp3 + xoff;
ny3 =round (256*translated[loop1][3].y) / temp3 + yoff;
DrawPoly(nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3,13,Vaddr);
}
}
}
// Procedure Whizz (sub:boolean);
void Whizz(int sub, int* deg)
{
int loop1;
for(loop1=-64;loop1<=-5;loop1++)
{
zoff=loop1*8;
if(sub) xoff-=7; else xoff+=7;
RotatePoints(*deg,*deg,*deg);
DrawPoints();
WaitRetrace();
Flip2(Vaddr,VGA);
Cls(0,Vaddr);
(*deg)++; if(*deg==360)*deg=0;
}
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure MoveAround;
// { This is the main display procedure. Firstly it brings the object towards
// the viewer by increasing the Zoff, then passes control to the user }
void MoveAround()
{
int loop1,loop2;
int deg;
char ch;
deg=0;
ch=0x0;
yoff=100;
xoff=350;
Cls(0,Vaddr);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=A[loop1][loop2][0];
Lines[loop1][loop2].y=A[loop1][loop2][1];
Lines[loop1][loop2].z=A[loop1][loop2][2];
}
Whizz (1, °);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=S[loop1][loop2][0];
Lines[loop1][loop2].y=S[loop1][loop2][1];
Lines[loop1][loop2].z=S[loop1][loop2][2];
}
Whizz (0, °);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=P[loop1][loop2][0];
Lines[loop1][loop2].y=P[loop1][loop2][1];
Lines[loop1][loop2].z=P[loop1][loop2][2];
}
Whizz (1, °);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=H[loop1][loop2][0];
Lines[loop1][loop2].y=H[loop1][loop2][1];
Lines[loop1][loop2].z=H[loop1][loop2][2];
}
Whizz (0, °);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=Y[loop1][loop2][0];
Lines[loop1][loop2].y=Y[loop1][loop2][1];
Lines[loop1][loop2].z=Y[loop1][loop2][2];
}
Whizz (1, °);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=X[loop1][loop2][0];
Lines[loop1][loop2].y=X[loop1][loop2][1];
Lines[loop1][loop2].z=X[loop1][loop2][2];
}
Whizz (0, °);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=I[loop1][loop2][0];
Lines[loop1][loop2].y=I[loop1][loop2][1];
Lines[loop1][loop2].z=I[loop1][loop2][2];
}
Whizz (1, °);
for(loop1=0;loop1<maxpolys;loop1++)
for(loop2=0;loop2<4;loop2++)
{
Lines[loop1][loop2].x=A[loop1][loop2][0];
Lines[loop1][loop2].y=A[loop1][loop2][1];
Lines[loop1][loop2].z=A[loop1][loop2][2];
}
Whizz (0, °);
Cls (0,Vaddr);
Cls (0,VGA);
xoff = 160;
while(ch!=0x1b) // escape
{
if(_bios_keybrd(_KEYBRD_READY))
{
ch=(getch()&0x00ff);
if(ch==0x71)break; // 'q'
if(ch==0x51)break; // 'Q'
if(ch==0x1b)break; // ESC
if(ch=='Z')zoff+=5;
if(ch=='z')zoff-=5;
if(ch=='X')xoff+=5;
if(ch=='x')xoff-=5;
if(ch=='Y')yoff+=5;
if(ch=='y')yoff-=5;
}
DrawPoints();
WaitRetrace();
Flip2(Vaddr,VGA);
Cls(0,Vaddr);
RotatePoints(deg,deg,deg);
deg++; if(deg==360)deg=0;
}
}
void main()
{
SetUpVirtual();
_clearscreen(_GCLEARSCREEN);
SetMCGA();
SetUpPoints();
MoveAround();
SetText();
}
/*
Sorry, I got too lazy to convert these to printf's!
Writeln ('Hello there! Varsity has begun once again, so it is once again');
Writeln ('back to the grindstone ;-) ... anyway, this tutorial is, by');
Writeln ('popular demand, on poly-filling, in relation to 3-D solids.');
Writeln;
Writeln ('In this program, the letters of ASPHYXIA will fly past you. As you');
Writeln ('will see, they are solid, not wireframe. After the last letter has');
Writeln ('flown by, a large A will be left in the middle of the screen.');
Writeln;
Writeln ('You will be able to move it around the screen, and you will notice');
Writeln ('that it may have bits only half on the screen, i.e. clipping is');
Writeln ('perfomed. To control it use the following : "A" and "Z" control the Z');
Writeln ('movement, "," and "." control the X movement, and "S" and "X"');
Writeln ('control the Y movement. I have not included rotation control, but');
Writeln ('it should be easy enough to put in yourself ... if you have any');
Writeln ('hassles, leave me mail.');
Writeln;
Writeln ('I hope this is what you wanted...leave me mail for new ideas.');
writeln;
writeln;
Write (' Hit any key to contine ...');
Readkey;
SetMCGA;
SetUpPoints;
MoveAround;
SetText;
ShutDown;
Writeln ('All done. This concludes the ninth sample program in the ASPHYXIA');
Writeln ('Training series. You may reach DENTHOR under the names of GRANT');
Writeln ('SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid');
Writeln ('Connectix BBS user, and occasionally read RSAProg.');
Writeln ('The numbers are available in the main text. You may also write to me at:');
Writeln (' Grant Smith');
Writeln (' P.O. Box 270');
Writeln (' Kloof');
Writeln (' 3640');
Writeln ('I hope to hear from you soon!');
Writeln; Writeln;
Write ('Hit any key to exit ...');
Readkey;
END.
*/